package social

import (
    "context"
    "errors"
    "log"
    "sync"

    "github.com/gomodule/redigo/redis"
    pb "your_project/proto"
    "your_project/data"
)

// SocialManager 社交管理器
type SocialManager struct {
    friendsMutex sync.RWMutex
    guildsMutex  sync.RWMutex
    
    // Redis连接池
    redisPool *data.RedisPool
}

// GetInstance 获取社交管理器实例
func GetInstance() *SocialManager {
    return socialManagerInstance
}

var socialManagerInstance = &SocialManager{}

// Init 初始化社交管理器
func (sm *SocialManager) Init() {
    sm.redisPool = data.GetRedisPool()
    log.Println("Social manager initialized")
}

// ------------------------ 好友系统 ------------------------

// AddFriend 添加好友
func (sm *SocialManager) AddFriend(playerID, friendID int64) error {
    if playerID == friendID {
        return errors.New("cannot add self as friend")
    }
    
    conn := sm.redisPool.Get()
    defer conn.Close()
    
    // 检查是否已经是好友
    isFriend, err := redis.Bool(conn.Do("SISMEMBER", fmt.Sprintf("friends:%d", playerID), friendID))
    if err != nil {
        return err
    }
    
    if isFriend {
        return errors.New("already friends")
    }
    
    // 添加好友关系（双向）
    _, err = conn.Do("SADD", fmt.Sprintf("friends:%d", playerID), friendID)
    if err != nil {
        return err
    }
    
    _, err = conn.Do("SADD", fmt.Sprintf("friends:%d", friendID), playerID)
    return err
}

// RemoveFriend 移除好友
func (sm *SocialManager) RemoveFriend(playerID, friendID int64) error {
    conn := sm.redisPool.Get()
    defer conn.Close()
    
    // 移除好友关系（双向）
    _, err := conn.Do("SREM", fmt.Sprintf("friends:%d", playerID), friendID)
    if err != nil {
        return err
    }
    
    _, err = conn.Do("SREM", fmt.Sprintf("friends:%d", friendID), playerID)
    return err
}

// GetFriends 获取好友列表
func (sm *SocialManager) GetFriends(playerID int64) ([]int64, error) {
    conn := sm.redisPool.Get()
    defer conn.Close()
    
    friends, err := redis.Int64s(conn.Do("SMEMBERS", fmt.Sprintf("friends:%d", playerID)))
    return friends, err
}

// IsFriend 检查是否为好友
func (sm *SocialManager) IsFriend(playerID, friendID int64) (bool, error) {
    conn := sm.redisPool.Get()
    defer conn.Close()
    
    return redis.Bool(conn.Do("SISMEMBER", fmt.Sprintf("friends:%d", playerID), friendID))
}

// ------------------------ 公会系统 ------------------------

// CreateGuild 创建公会
func (sm *SocialManager) CreateGuild(playerID int64, name, desc string) (int64, error) {
    conn := sm.redisPool.Get()
    defer conn.Close()
    
    // 获取下一个公会ID
    guildID, err := redis.Int64(conn.Do("INCR", "guild:next_id"))
    if err != nil {
        return 0, err
    }
    
    // 创建公会
    guildKey := fmt.Sprintf("guild:%d", guildID)
    _, err = conn.Do("HMSET", guildKey, 
        "id", guildID,
        "name", name,
        "desc", desc,
        "master", playerID,
        "create_time", time.Now().Unix())
    if err != nil {
        return 0, err
    }
    
    // 将玩家添加到公会成员列表
    _, err = conn.Do("SADD", fmt.Sprintf("guild:%d:members", guildID), playerID)
    if err != nil {
        return 0, err
    }
    
    // 设置玩家的公会ID
    _, err = conn.Do("SET", fmt.Sprintf("player:%d:guild", playerID), guildID)
    
    return guildID, err
}

// JoinGuild 加入公会
func (sm *SocialManager) JoinGuild(playerID, guildID int64) error {
    conn := sm.redisPool.Get()
    defer conn.Close()
    
    // 检查玩家是否已有公会
    currentGuildID, err := redis.Int64(conn.Do("GET", fmt.Sprintf("player:%d:guild", playerID)))
    if err == nil && currentGuildID > 0 {
        return errors.New("already in a guild")
    }
    
    // 将玩家添加到公会成员列表
    _, err = conn.Do("SADD", fmt.Sprintf("guild:%d:members", guildID), playerID)
    if err != nil {
        return err
    }
    
    // 设置玩家的公会ID
    _, err = conn.Do("SET", fmt.Sprintf("player:%d:guild", playerID), guildID)
    
    return err
}

// LeaveGuild 离开公会
func (sm *SocialManager) LeaveGuild(playerID int64) error {
    conn := sm.redisPool.Get()
    defer conn.Close()
    
    // 获取玩家的公会ID
    guildID, err := redis.Int64(conn.Do("GET", fmt.Sprintf("player:%d:guild", playerID)))
    if err != nil || guildID <= 0 {
        return errors.New("not in a guild")
    }
    
    // 从公会成员列表中移除玩家
    _, err = conn.Do("SREM", fmt.Sprintf("guild:%d:members", guildID), playerID)
    if err != nil {
        return err
    }
    
    // 清除玩家的公会ID
    _, err = conn.Do("DEL", fmt.Sprintf("player:%d:guild", playerID))
    
    // 如果是会长，解散公会
    isMaster, err := redis.Bool(conn.Do("HGET", fmt.Sprintf("guild:%d", guildID), "master"))
    if err == nil && isMaster {
        sm disbandGuild(guildID)
    }
    
    return err
}

// GetGuildMembers 获取公会成员
func (sm *SocialManager) GetGuildMembers(guildID int64) ([]int64, error) {
    conn := sm.redisPool.Get()
    defer conn.Close()
    
    return redis.Int64s(conn.Do("SMEMBERS", fmt.Sprintf("guild:%d:members", guildID)))
}

// disbandGuild 解散公会
func (sm *SocialManager) disbandGuild(guildID int64) error {
    conn := sm.redisPool.Get()
    defer conn.Close()
    
    // 获取公会成员
    members, err := redis.Int64s(conn.Do("SMEMBERS", fmt.Sprintf("guild:%d:members", guildID)))
    if err != nil {
        return err
    }
    
    // 清除所有成员的公会ID
    for _, memberID := range members {
        conn.Do("DEL", fmt.Sprintf("player:%d:guild", memberID))
    }
    
    // 删除公会相关键
    conn.Do("DEL", fmt.Sprintf("guild:%d", guildID))
    conn.Do("DEL", fmt.Sprintf("guild:%d:members", guildID))
    
    return nil
}    